#pragma once
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cassert>

template <typename T>
class LockFreeRingBuffer
{
public:
    explicit LockFreeRingBuffer(size_t capacity);
    ~LockFreeRingBuffer();

    bool push(const T &item);
    bool pop(T &item);

    bool empty() const;
    bool full() const;
    size_t size() const;

private:
    size_t next(size_t idx) const;

    const size_t capacity_;
    T *buffer_;

    alignas(64) std::atomic<size_t> head_;
    alignas(64) std::atomic<size_t> tail_;
};
